#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<getopt.h>
#include<netdb.h>
#define MSG_STR "Welcome to LiYi studio client"

int main(int argc,char **argv)
{
	int 			sockfd=-1;
	int 			rv=-1;
	int 			port=0;
	char			*servip=NULL;
	char			**pIP=NULL;
	struct sockaddr_in	servaddr;
	char			buf[1024];
	struct hostent		*host=NULL;
	char			*domain=NULL;
	int 			ch=0;
	char			str[32];

	struct option		opts[]={
		{"ipaddr",required_argument,NULL,'i'},
		{"port",required_argument,NULL,'P'},
		{"domain",required_argument,NULL,'d'},
		{NULL,0,NULL,0}
	};//参数解析

	while((ch=getopt_long(argc,argv,"i:p:d",opts,NULL))!=-1)
	{
		switch(ch)
		{
			case 'i':
				servip=optarg;
				break;
			case 'p':
				port=atoi(optarg);
				break;
			case 'd':
				{
					domain=optarg;
					printf("Domain :%s\n",domain);
					break;
				}
			default:
				 printf("Unknown return val %d\n",ch);
		}
	}


	//选择ip地址或者域名
	//如果都不是则直接结束此次通信 
	if(!port | !(!domain ^ !servip))
	{
		printf("Program usage : %s [SERVERIP] [PORT] or [Domain][PORT] \n",argv[0]);
		return -1;
	}

	//如果输入的不是IP
	if(!servip)
	{
		if((host=gethostbyname(domain))==NULL)
		{
			printf("Gethostbyname error:%s\n",strerror(errno));
			return -1;
		}
		switch(host->h_addrtype)
		{
			case AF_INET:
			case AF_INET6:
				pIP=host->h_addr_list;
				for(;*pIP!=NULL;pIP++)
				{
					printf("IP  address :%s\n",inet_ntop(host->h_addrtype,*pIP,str,sizeof(str)));
				}
				servip=str;
				break;
			default:
				printf("Unknown address type\n");
				break;
		}
	}
	printf("IP：%s\n",servip);

	
	//创建SOCKET
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		printf("Create a socket[%d] failure: %s\n",sockfd,strerror(errno));
		return -1;
	}
	printf("Create socket[%d] successfully!\n",sockfd);

	//连接
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(port);
	//将字符串转成网络字序
	inet_aton(servip,&servaddr.sin_addr);
	endhostent();//释放结构体
	host=NULL;//防止野指针

	rv=connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
	if(rv<0)
	{
		printf("Connect to server[%s] failure: %s\n",servip,strerror(errno));
		return -2;
	}
	printf("Connect to server[%s:%d] successfully!\n",servip,port);

	while(1)
	{
		//写
		rv=write(sockfd,MSG_STR,sizeof(MSG_STR));
		if(rv<0)
		{
			printf("Write to server by sockfd[%d] failure:%s\n",sockfd,strerror(errno));
			return -3;
		}
		printf("Write to server by sockfd[%d] successfully!\n",sockfd);

		//读
		memset(buf,0,sizeof(buf));
		rv=read(sockfd,buf,sizeof(buf));
		if(rv==0)
		{
			printf("Sockfd[%d] get disconnected!\n",sockfd);
			break;
		}
		else if(rv<0)
		{
			printf("Read server by sockfd[%d] failure:%s\n",sockfd,strerror(errno));
			break;
		}
		else if(rv>0)
		{
			printf("Read data %d bytes from server %s  successfully!\n",rv,buf);
		}
	}
	close(sockfd);
}

		
